package com.fadis.data;

import com.fadis.FadisException;

import java.io.UnsupportedEncodingException;
import java.util.BitSet;

public class Sds {

    public int len = 0;

    public int free = 0;

    public byte buf[] = new byte[0];


    public static Sds sdsnew(String s){
        try {
            Sds m = new Sds();
            byte[] buf = s.getBytes("utf-8");
            m.buf = buf;
            m.len = buf.length;
            m.free = 0;
            return m;
        } catch (UnsupportedEncodingException e) {
            throw new FadisException(1002, e.getMessage());
        }
    }

    public static Sds sdsempty(){
        Sds m = new Sds();
        return m;
    }

    public Sds sdsdup(){
        Sds m = new Sds();
        m.buf = new byte[this.len];
        for (int i = 0; i < this.len; i++) {
            m.buf[i] = this.buf[i];
        }
        m.len = m.len;
        m.free = 0;
        return m;
    }

    public void sdsfree(){
        this.buf = new byte[0];
        this.len = 0;
        this.free = 0;
    }

    public void sdsclear(){
        this.free += this.len;
        this.len = 0;

    }

    public int sdslen(){
        return this.len;
    }

    public int sdsavail(){
        return this.free;
    }

    public void sdscat(String s){
        try {
            byte[] buf2 = s.getBytes("utf-8");
            this.sdscat(buf2);
        } catch (UnsupportedEncodingException e) {
            throw new FadisException(1002, e.getMessage());
        }
    }

    public void sdscat(Sds s){
       this.sdscat(s.buf);
    }

    public void sdscpy(String s){
        try {
            byte[] buf2 = s.getBytes("utf-8");
            realloc(buf2.length);
            for (int i = 0; i < buf2.length; i++) {
                this.buf[i] = buf2[i];
            }
            int total = this.len + this.free;
            this.len = buf2.length;
            this.free = total - this.len;
        } catch (UnsupportedEncodingException e) {
            throw new FadisException(1002, e.getMessage());
        }
    }

    public void sdsgrowzero(int newLen){
        if(this.len >= newLen) return;
        int total = this.len + this.free;
        if(total < newLen){
            this.realloc(newLen);
        }
        total = this.len + this.free;
        for (int i = this.len; i < total; i++) {
            this.buf[i] = 0;
        }
        this.len = newLen;
        this.free = total - this.len;
    }

    public void sdsrange(int startInclude, int endInclude){
        if(startInclude < 0){
            throw new FadisException(1002, "illeggle index " + startInclude);
        }
        if(endInclude >= this.len - 1){
            throw new FadisException(1002, "illeggle index " + endInclude);
        }

        int total = this.len + this.free;
        int newLen = endInclude - startInclude + 1;
        if(startInclude == 0){
            this.len = newLen;
            this.free = total - this.len;
        }else{
            int dest = 0;
            int src = startInclude;
            for (int i = 0; i < newLen; i++) {
                this.buf[dest + i] = this.buf[src + i];
            }
            this.len = newLen;
            this.free = total - this.len;
        }
    }

    private void sdscat(byte[] buf2){
        int newLen = buf2.length + this.len;
        this.realloc(newLen);
        for (int i = 0; i < this.free; i++) {
            this.buf[this.len + i] = buf2[i];
        }
        this.free -= buf2.length;
        this.len += buf2.length;
    }

    private void realloc(int totalCapacity){
        //if(this.len >= newLen) return;
        if(this.len + this.free >= totalCapacity) {
//            int total = this.len + this.free;
//            this.len = newLen;
//            this.free = total - this.len;
            return;
        }
        byte[] buf2 = new byte[totalCapacity];
        for (int i = 0; i < this.len; i++) {
            buf2[i] = this.buf[i];
        }
        this.buf = buf2;
        //this.len = newLen;
        this.free = totalCapacity - this.len;
    }
}
